package io.renren.modules.sys.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.renren.common.constant.Constant;
import io.renren.common.constant.Dict;
import io.renren.common.entity.pay.SysDeptEntity;
import io.renren.common.exception.ErrorCode;
import io.renren.common.exception.RenException;
import io.renren.common.page.PageData;
import io.renren.common.redis.RedisService;
import io.renren.common.service.impl.CrudServiceImpl;
import io.renren.common.utils.ConvertUtils;
import io.renren.common.utils.Result;
import io.renren.common.utils.TreeUtils;
import io.renren.modules.security.user.SecurityUser;
import io.renren.modules.security.user.UserDetail;
import io.renren.modules.sys.dao.SysDeptDao;
import io.renren.modules.sys.dto.SysDeptDTO;
import io.renren.modules.sys.enums.SuperAdminEnum;
import io.renren.modules.sys.service.SysDeptService;
import io.renren.modules.sys.service.SysUserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 商户管理
 *
 * @author Mark
 * @since 1.0.0 2019-04-05
 */
@Service
public class SysDeptServiceImpl extends CrudServiceImpl<SysDeptDao, SysDeptEntity, SysDeptDTO> implements SysDeptService {

	@Autowired
	private RedisService redisService;
	@Autowired
	private SysUserService sysUserService;

	@Override
	public QueryWrapper<SysDeptEntity> getWrapper(Map<String, Object> params) {
		String id = (String) params.get("id");
		String name = (String) params.get("name");
		String mobile = (String) params.get("mobile");

		QueryWrapper<SysDeptEntity> wrapper = new QueryWrapper<>();
		wrapper.like(StringUtils.isNotBlank(id), "id", id);
		wrapper.like(StringUtils.isNotBlank(name), "name", name);
		wrapper.like(StringUtils.isNotBlank(mobile), "mobile", mobile);

		UserDetail user = SecurityUser.getUser();
		if (user.getSuperAdmin() == SuperAdminEnum.NO.value()) {
			//wrapper.in("id", user.getDeptId());
			wrapper.in("id", getSubDeptIdList(user.getDeptId()));

		}

		return wrapper;
	}

	/**
	 * 商户查询
	 */
	@Override
	public PageData<SysDeptDTO> page(Map<String, Object> params) {
		IPage<SysDeptEntity> page = getPage(params, Constant.CREATE_DATE, false);
		IPage<SysDeptEntity> selectPage = baseDao.selectPage(page, getWrapper(params));

		return getPageData(selectPage, SysDeptDTO.class);
	}

	@Override
	public List<Long> getSubDeptIdList(Long id) {
		Map<String, Object> params = new HashMap<>();
		params.put("pid", id);
		List<SysDeptEntity> sysDeptEntities = baseDao.selectByMap(params);

		List<Long> collect = sysDeptEntities.stream().map(SysDeptEntity::getId).collect(Collectors.toList());
		collect.add(id);
		return collect;
	}

	@Override
	public List<SysDeptDTO> list(Map<String, Object> params) {
		//List<SysDeptEntity> selectList = baseDao.selectList(getWrapper(params));
		//普通管理员，只能查询所属部门及子部门的数据
		UserDetail user = SecurityUser.getUser();
		if (user.getSuperAdmin() == SuperAdminEnum.NO.value()) {
			params.put("deptIdList", getSubDeptIdList(user.getDeptId()));
		}

		//查询部门列表
		List<SysDeptEntity> entityList = baseDao.getList(params);

		List<SysDeptDTO> dtoList = ConvertUtils.sourceToTarget(entityList, SysDeptDTO.class);

		return TreeUtils.build(dtoList);


		//return ConvertUtils.sourceToTarget(selectList, SysDeptDTO.class);

	}

	@Override
	public Result saveDept(SysDeptDTO dto) {
		if (dto.getName().length() > 20) {
			return new Result().error("\"部门名称长度不能大于20个字符\"");
		}
		SysDeptEntity entity = ConvertUtils.sourceToTarget(dto, currentModelClass());
		if (baseDao.insert(entity) != 1) {
			return new Result<SysDeptDTO>().error("新增部门失败");
		}
		redisService.setHashMap(Dict.MERCHANT, entity.getId(), JSON.toJSONString(entity));
		return new Result<>().ok(entity);
	}

	@Override
	public PageData<SysDeptDTO> pageList(Map<String, Object> params) {
		// TODO Auto-generated method stub
		IPage<SysDeptEntity> page = getPage(params, Constant.CREATE_DATE, false);
		//普通管理员，只能查询所属部门及子部门的数据
		UserDetail user = SecurityUser.getUser();
		if (user.getSuperAdmin() == SuperAdminEnum.NO.value()) {
			params.put("deptIdList", getSubDeptIdList(user.getDeptId()));
		}
		//查询部门列表
		List<SysDeptEntity> entityList = baseDao.getList(params);

		List<SysDeptDTO> dtoList = ConvertUtils.sourceToTarget(entityList, SysDeptDTO.class);

		return new PageData<>(TreeUtils.build(dtoList), page.getTotal());
	}

	/**
	 * 获取所有上级部门ID
	 *
	 * @param pid 上级ID
	 */
	private String getPidList(Long pid) {
		//顶级部门，无上级部门
		if (Constant.DEPT_ROOT.equals(pid)) {
			return Constant.DEPT_ROOT + "";
		}

		//所有部门的id、pid列表
		List<SysDeptEntity> deptList = baseDao.getIdAndPidList();

		//list转map
		Map<Long, SysDeptEntity> map = new HashMap<>(deptList.size());
		for (SysDeptEntity entity : deptList) {
			map.put(entity.getId(), entity);
		}

		//递归查询所有上级部门ID列表
		List<Long> pidList = new ArrayList<>();
		getPidTree(pid, map, pidList);

		return StringUtils.join(pidList, ",");
	}

	private void getPidTree(Long pid, Map<Long, SysDeptEntity> map, List<Long> pidList) {
		//顶级部门，无上级部门
		if (Constant.DEPT_ROOT.equals(pid)) {
			return;
		}

		//上级部门存在
		SysDeptEntity parent = map.get(pid);
		if (parent != null) {
			getPidTree(parent.getPid(), map, pidList);
		}

		pidList.add(pid);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Result updateDept(SysDeptDTO dto) {
		// TODO Auto-generated method stub
		SysDeptDTO sysDeptDTO = this.get(dto.getId());
		if (sysDeptDTO == null) {
			return new Result().error("商户不存在，请添加后再次修改");
		}
		SysDeptEntity entity = ConvertUtils.sourceToTarget(dto, SysDeptEntity.class);

		//上级部门不能为自身
		if (entity.getId().equals(entity.getPid())) {
			throw new RenException(ErrorCode.SUPERIOR_DEPT_ERROR);
		}
		UserDetail user = (UserDetail) SecurityUtils.getSubject().getPrincipal();
		dto.setUpdateDate(DateUtil.date());
		dto.setUpdater(user.getId());
		this.updateById(entity);
		redisService.setHashMap(Dict.MERCHANT, dto.getId(), JSON.toJSONString(dto));
		return new Result<>().ok(entity);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void delete(Long id) {
		// TODO Auto-generated method stub
		//判断是否有子部门
		List<Long> subList = getSubDeptIdList(id);
		if (subList.size() > 1) {
			throw new RenException(ErrorCode.DEPT_SUB_DELETE_ERROR);
		}

		//判断部门下面是否有用户
		int count = sysUserService.getCountByDeptId(id);
		if (count > 0) {
			throw new RenException(ErrorCode.DEPT_USER_DELETE_ERROR);
		}
		SysDeptEntity entity = baseDao.selectById(id);
		//删除
		baseDao.deleteById(id);
		redisService.deletHashMap(Dict.MERCHANT, id);
	}
}